using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Unity.VisualScripting;
using UnityEditorInternal;
using UnityEngine;

public class Player_States : IState
{
    protected Player_FSM stateMachine;
    protected Animator animator;
    
    protected float curretnSpeed;

    protected float stateStartTime;
    protected float StateDuration => Time.time - stateStartTime;
    protected bool IsStateFinished => StateDuration >= animator.GetCurrentAnimatorStateInfo(0).length;  //判断当前状态的动画是否播放完毕 会很常用
    public virtual void Enter()
    {
        stateStartTime = Time.time;
    }

    public virtual void Exit()
    {
        
    }

    public virtual void LogicUpdate()
    {
        
    }

    public virtual void PhysicsUpdate()
    {
        
    }
}
public class PlayerState_Idle : Player_States     //每个状态的结构都基本一致 状态机的好处在于每个状态的逻辑各自独立 不会出现if嵌套的情况
{
    public PlayerState_Idle(Player_FSM stateMachine, Animator animator) //构造函数
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        curretnSpeed = stateMachine.MoveSpeed;
        animator.Play("Idle");
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (stateMachine.IsHit)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Hit);
        }
        if (stateMachine.IsTouch)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Touch);
        }
        if (stateMachine.IsReact && Input.GetKey(KeyCode.E))         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.React);
        }
        if (stateMachine.HasJumpBuffer || stateMachine.IsJump)      //跳转到跳跃状态
        {
            stateMachine.StateSwitch(PlayerState.Jump);
        }
        if (!stateMachine.IsGround)         //跳转到下落状态
        {
            stateMachine.StateSwitch(PlayerState.Fall);
        }
        if (stateMachine.IsMove)        //跳转到移动状态
        {
            stateMachine.StateSwitch(PlayerState.Walk);
        }
        curretnSpeed = Mathf.MoveTowards(curretnSpeed,0,stateMachine.GetDeceleration()* Time.deltaTime);  //速度值的逻辑变更
    }
    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
        stateMachine.SetVelocityX(curretnSpeed);  //速度值的物理变更
    }
    public override void Exit()
    {
        base.Exit();
    }
}//其他的状态逻辑也比较清晰 这里就不写注释了 骷髅小兵同样使用状态机进行制作 逻辑与玩家完全一致 
public class PlayerState_Walk : Player_States
{
    public PlayerState_Walk(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("Walk");
        curretnSpeed = stateMachine.MoveSpeed;
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        
        if (stateMachine.IsHit)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Hit);
        }
        if (stateMachine.IsTouch)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Touch);
        }
        if (stateMachine.IsReact && Input.GetKey(KeyCode.E))         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.React);
        }
        if (stateMachine.HasJumpBuffer || stateMachine.IsJump)      //跳转到跳跃状态
        {
            stateMachine.StateSwitch(PlayerState.Jump);
        }
        if (!stateMachine.IsGround)         //跳转到下落状态
        {
            stateMachine.StateSwitch(PlayerState.Fall);
        }
        if (!stateMachine.IsMove)
        {
            stateMachine.StateSwitch(PlayerState.Idle);
        }
        curretnSpeed = Mathf.MoveTowards(curretnSpeed, stateMachine.GetRunSpeed() * stateMachine.MoveX, stateMachine.GetAcceleration() * Time.deltaTime);
    }
    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
        stateMachine.Flip();
        stateMachine.SetVelocityX(curretnSpeed);
    }
    public override void Exit()
    {
        base.Exit();
    }
}
public class PlayerState_Jump : Player_States
{
    public PlayerState_Jump(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        stateMachine.SetVelocityY(stateMachine.GetJumpForce());
        animator.Play("Jump");
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        
        if (stateMachine.IsHit)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Hit);
        }
        if (stateMachine.IsTouch)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Touch);
        }
        if (stateMachine.IsReact && Input.GetKey(KeyCode.E))         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.React);
        }
        if (stateMachine.IsFall)
        {
            stateMachine.StateSwitch(PlayerState.Fall);
        }
        if (stateMachine.IsHit)
        {
            stateMachine.StateSwitch(PlayerState.Hit);
        }
    }
    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
        stateMachine.FlipInAir();
    }
    public override void Exit()
    {
        base.Exit();
    }
}
public class PlayerState_Fall : Player_States
{
    private float init_pos_y;
    public PlayerState_Fall(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("Fall");
        init_pos_y = stateMachine.transform.position.y;
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (stateMachine.IsHit)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Hit);
        }
        if (stateMachine.IsTouch)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Touch);
        }
        if (stateMachine.IsReact && Input.GetKey(KeyCode.E))         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.React);
        }
        if (stateMachine.IsJump)
        {
            stateMachine.SetJumpBuffer();
        }
        if (stateMachine.IsGround)
        {
            stateMachine.StateSwitch(PlayerState.Land);
        }
    }
    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
        stateMachine.FlipInAir();
    }
    public override void Exit()
    {
        base.Exit();
    }
}
public class PlayerState_Land : Player_States
{
    public PlayerState_Land(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("Land");
        stateMachine.SetVelocityX(0);
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (stateMachine.IsHit)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Hit);
        }
        if (stateMachine.IsTouch)         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.Touch);
        }
        if (stateMachine.IsReact && Input.GetKey(KeyCode.E))         //跳转到受击状态
        {
            stateMachine.StateSwitch(PlayerState.React);
        }
        if (stateMachine.HasJumpBuffer || stateMachine.IsJump)
        {
            stateMachine.StateSwitch(PlayerState.Jump);
        }
        if (IsStateFinished)
        {
            stateMachine.StateSwitch(PlayerState.Idle);
        }
    }
    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
    }
    public override void Exit()
    {
        base.Exit();
    }
}

public class PlayerState_Touch : Player_States
{
    public PlayerState_Touch(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("Touch");
        stateMachine.SetVelocity(new Vector2(0, 0));
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (IsStateFinished)
        {
            stateMachine.StateSwitch(PlayerState.Fall);
        }
    }

    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
    }

    public override void Exit()
    {
        base.Exit();
    }
}

public class PlayerState_React : Player_States
{
    public PlayerState_React(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("React");
        stateMachine.SetVelocity(new Vector2(0,0));
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (IsStateFinished)
        {
            stateMachine.StateSwitch(PlayerState.Idle);
        }
    }
    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
    }
    public override void Exit()
    {
        base.Exit();
    }
}

public class PlayerState_Hit : Player_States
{

    public PlayerState_Hit(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        stateMachine.IsHit = false;
        animator.Play("Hit",0,0);
        stateMachine.SetVelocityX(0);
        stateMachine.SetVelocityY(0);
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (IsStateFinished)
        {
            stateMachine.StateSwitch(PlayerState.Idle);
        }
    }
    public override void PhysicsUpdate()
    {
        base.PhysicsUpdate();
    }
    public override void Exit()
    {
        base.Exit();     
    }
}